#include "communicate.h"

#include<sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#include <sched.h>

#define CHECK_RESPONSE 0
#define PORT 8507

pthread_mutex_t mutex;

int create_communication(char* ip){
	int s;										/*s为socket描述符*/
	struct sockaddr_in server_addr;			/*服务器地址结构*/

	s = socket(AF_INET, SOCK_STREAM, 0); 		/*建立一个流式套接字 */
	if(s < 0){									/*出错*/
		printf("socket error\n");
		return -1;
	}	
	
	/*设置服务器地址*/
	bzero(&server_addr, sizeof(server_addr));	/*清零*/
	server_addr.sin_family = AF_INET;					/*协议族*/
	server_addr.sin_addr.s_addr = htonl(INADDR_ANY);	/*本地地址*/
	server_addr.sin_port = htons(PORT);				/*服务器端口*/
	
	/*将字符串类型的IP地址转为整型*/
	inet_pton(AF_INET, ip, &server_addr.sin_addr);	

	/*连接服务器*/
	int ret = connect(s, (struct sockaddr*)&server_addr, sizeof(struct sockaddr));
	if(ret != 0){
		printf("连接错误，错误信息:%s\n", strerror(errno));
		return -1;	
	}

	return s;
}

float probability_drl[16] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16};

char category_format[] = "{\
	\"flip\":%d;\
	\"set_byte\":%d;\
	\"set_word\":%d;\
	\"set_dword\":%d;\
	\"subtract_byte\":%d;\
	\"add_byte\":%d;\
	\"subtract_word\":%d;\
	\"add_word\":%d;\
	\"subtract_dword\":%d;\
	\"add_dword\":%d;\
	\"randorm_set\":%d;\
	\"delete_byte1\":%d;\
	\"delete_byte2\":%d;\
	\"replace25\":%d;\
	\"random_replace\":%d;\
	\"overwrite\":%d;}";

int format_category(const float* data, size_t len, char* format_str){
	size_t n = sprintf(format_str, category_format,
		(int)(data[0] * 100.00 + 0.5),
		(int)(data[1] * 100.00 + 0.5),
		(int)(data[2] * 100.00 + 0.5),
		(int)(data[3] * 100.00 + 0.5),
		(int)(data[4] * 100.00 + 0.5),
		(int)(data[5] * 100.00 + 0.5),
		(int)(data[6] * 100.00 + 0.5),
		(int)(data[7] * 100.00 + 0.5),
		(int)(data[8] * 100.00 + 0.5),
		(int)(data[9] * 100.00 + 0.5),
		(int)(data[10] * 100.00 + 0.5),
		(int)(data[11] * 100.00 + 0.5),
		(int)(data[12] * 100.00 + 0.5),
		(int)(data[13] * 100.00 + 0.5),
		(int)(data[14] * 100.00 + 0.5),
		(int)(data[15] * 100.00 + 0.5)	
	);
	return n;
}

void upload_category_pthread(upload_arg_t* arg){
	int ret = upload_category(arg->connfd, arg->data, arg->len);
}

int upload_category(int connfd, const float* data, size_t len){
	char str[512];
	size_t n = format_category(data, len, str);
#if CHECK_RESPONSE
	// 判断是否上传成功
	char res[1024];
	int32_t is_uploaded = 0;
	while(!is_uploaded){
		write(connfd, data, len);
		int len = read(connfd, res, 1024);
		printf("get result from server, len:%d, %s\n", len, res);
		if(len < 0 || strcmp(res, "OK") != 0){
			printf("error!\n");
			printf("res:%s\n", res);
			printf("retry upload the category\n");
		}else{
			printf("get result from server: %s\n", res);
			is_uploaded = 1;
		}
	}
#else
	pthread_mutex_lock(&mutex);
	printf("upload content:%s\n", str);
	write(connfd, str, n);
	pthread_mutex_unlock(&mutex);
#endif
	return 0;
}

int close_communication(int connfd){
	close(connfd);
	pthread_mutex_destroy(&mutex);
	return 0;
}

int main(void){
	int s = create_communication("127.0.0.1");
	//-----------------------------------------------------------//
	// char str[512];
	// format_category(probability_drl, str);
	// printf("%s\n", str);
	//-----------------------------------------------------------//
	// upload_category(s, probability_drl, 16);
	// close_communication(s);	
	//-----------------------------------------------------------//
	pthread_t upload_id;
	upload_arg_t args;
	args.connfd = s;
	args.data = probability_drl;
	args.len = 16;
	int ret = 0;
	ret = pthread_create(&upload_id, NULL, (void *)upload_category_pthread, &args);
	if(ret == -1){
		printf("pthread create failed\n");
		abort();
	}
	// pthread_join(upload_id, NULL);
	while(1){}
	//-----------------------------------------------------------//
	return 0;
}